#pragma once
#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include"Cond.hpp"
#include"Log.hpp"
#include"Mutex.hpp"
#include"Thread.hpp"
namespace ThreadPoolModule
{
    using namespace ThreadModlue;
    using namespace LogModule;
    using namespace CondModule;
    using namespace MuteModule;
    static const int gnum = 5;
    template <typename T>
    class ThreadPool
    {
    private:
        void WeakUpAllThread()
        {
            LockGuard t(_mutex);
            if(_isnumber)
            {
                _cond.Broadcast();
                LOG(LogLeve1::DEBUG) << "唤醒所有线程";
            }
        }
        void WakeUpOne()
        {
            
            _cond.Signal();
            LOG(LogLeve1::DEBUG) << "唤醒一个线程";
        }
    public:
        ThreadPool(int num = gnum)
        :_num(num),
         _isruning(false),
         _isnumber(0)
        {
            //创建多个线程
            for(int i = 0; i < _num; i++)
            {
                _threads.emplace_back(
                    [this](){
                        HanderTask();
                    }
                );

                //_threads.emplace_back(HanderTask);
                LOG(LogLeve1::DEBUG) << "创建线程成功";
            }
        }
        void Start()
        {
            if( _isruning)
            {
                 return;
            }
            _isruning = true;
            //启动多个线程
            for(auto& thread : _threads)
            {
                thread.Start();
                LOG(LogLeve1::DEBUG) << "启动线程成功";

            }
        }
        void join()
        {
            //依次回收线程
            for(auto& thread : _threads)
            {
                thread.Join();
                LOG(LogLeve1::DEBUG) << "线程回收成功";
            }
        }
        void HanderTask()   // 他是成员函数，直接使用，有隐藏的this指针，并不是void（）类型的函
        {
            char name[128];
            pthread_getname_np(pthread_self(), name, sizeof(name));
            while(true)
            {
                T tmp;
                {
                    LockGuard t(_mutex);
                    while(_taskq.empty() && _isruning)
                    {
                        //break;
                        //没有任务了暂时让线程进入休眠状态
                        _isnumber++;
                        _cond.Wait(_mutex);
                        _isnumber--;
                    }
                    if(!_isruning && _taskq.empty())
                    {
                        LOG(LogLeve1::DEBUG) << "线程退出" << name;
                        break;
                    }
                    //一定有任务
                    tmp = _taskq.front();
                    _taskq.pop();
                }
                tmp();
                //sleep(1);
                
            }
        }
        void Stop()
        {
            if(!_isruning)
            {
                return;
            }
            _isruning = false;
            //唤醒所有线程
            WeakUpAllThread();
        }
        bool Enqueue(const T &in)
        {
            
            if(_isruning)
            {
                LockGuard t(_mutex);
                _taskq.push(in);
                LOG(LogLeve1::DEBUG) << "放入一个任务";
                if(_threads.size() == _isnumber)
                {
                    WakeUpOne();
                    return true;
                }
            }
            return false;
        }
        ~ThreadPool()
        {

        }
    private:
        std::vector<Thread> _threads;//创建线程
        int _num;//线程池中的,线程个数
        std::queue<T> _taskq;//任务队列
        Cond _cond;//条件变量
        Mutex _mutex;//锁

        bool _isruning;
        int _isnumber;
    };
}